package com.shine.cotrun.sql.hibernate;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import com.shine.cotrun.sql.hibernate.HibernateUtil;

/**
 * Hibernate的事务拦截器，通过Spring配置自动完成Hibernate的事务
 * @author zsy
 * @version May 17, 2009
 */
public class TransactionInterceptor implements MethodInterceptor {

	private ThreadLocal<Integer> lockDeep = new ThreadLocal<Integer>();

	public Object invoke(MethodInvocation arg0) throws Throwable {
		Object result = null;
		String methodName = arg0.getMethod().getName();
//		log.info("调用方法：" + methodName);
		boolean isBeginTransaction = false;//是否需要开事务
		try {
			//判断是否需要事务
			if (methodName.startsWith("tx")) {
				//线程变量中事务数加1
				Integer deep = lockDeep.get();
				if (deep == null || deep.intValue() == 0) {
					deep = new Integer(1);
				} else {
					deep = new Integer(deep.intValue() + 1);
				}
				lockDeep.set(deep);
				HibernateUtil.beginTransaction();//开始事务
				isBeginTransaction = true;//标志事务已打开
			}
			
			result = arg0.proceed();

			if (isBeginTransaction) {
				//线程变量
				int deep = lockDeep.get().intValue();
				deep = deep - 1;
				if (deep == 0) {
					HibernateUtil.commitTransaction();//提交事务
				}
				//若正常提交事务，线程变量中事务数减1
				lockDeep.set(new Integer(deep));
			}
		} catch(Exception e) {
			if (isBeginTransaction) {
				//线程变量
				int deep = lockDeep.get().intValue();
				deep = deep - 1;
				//线程变量中事务数减1
				lockDeep.set(new Integer(deep));
				
				HibernateUtil.rollbackTransaction();//异常则回滚DB事务
			}
//			log.error("TransactionInterceptor: 调用“" + methodName + "”失败：" + arg0.toString());
			throw e;
		} finally {
			Integer deep = lockDeep.get();
			if (deep == null || deep.intValue() == 0) {
				HibernateUtil.closeSession();//如果上下文有开启的session，关闭session
			}
		}
		return result;
	}
}
